package com.xqboss.apps.service.msg;

import cn.jiguang.common.ClientConfig;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.alibaba.fastjson2.JSON;
import com.xqboss.apps.enums.sys.PushJumpEnum;
import com.xqboss.apps.service.user.UserPushBindService;
import com.xqboss.common.config.XQBossConfig;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 推送服务
 * </p>
 *
 * @author Trent
 * @date 2023/9/1
 */
@Service
@Slf4j
public class PushService {

    @Value("${jpush.secret}")
    private String secret;

    @Value("${jpush.appKey}")
    private String appKey;

    @Value("${jpush.apnsProduction}")
    private Boolean apnsProduction;
    
    @Value("${jpush.aliasPrefix}")
    private String aliasPrefix;

    private volatile JPushClient jpushClient;

    @Autowired
    private UserPushBindService userPushBindService;

    private JPushClient getClient() {
        if (jpushClient == null) {
            synchronized (PushService.class) {
                if (jpushClient == null) {
                    jpushClient = new JPushClient(secret, appKey, null, ClientConfig.getInstance());
                }
            }
        }
        return jpushClient;
    }

    /**
     * 推送打卡消息
     */
    @Async("threadPoolTaskExecutor")
    public void pushPunchMsg(Long userId){
        push(userId, "打卡提醒", "喝水打卡倒计时还剩60秒，去打卡~", PushJumpEnum.PUNCH, "");
    }

    /**
     * 推送提醒打卡消息
     */
    @Async("threadPoolTaskExecutor")
    public void pushAlertPunchMsg(Long userId, String nickName){
        push(userId, "好友提醒打卡", StringUtils.format("{}提醒你来打卡啦，去打卡~", nickName), PushJumpEnum.PUNCH, "");
    }

    /**
     * 推送箱子发售消息
     */
    @Async("threadPoolTaskExecutor")
    public void pushBoxSaleMsg(String boxName, Long boxId){
        pushAll("抢购活动", StringUtils.format("“{}”开始发售啦，去抢购~", boxName), PushJumpEnum.BOX_DETAIL, String.valueOf(boxId));
    }


    /**
     * 推送箱子上架消息
     */
    @Async("threadPoolTaskExecutor")
    public void pushBoxSaleableMsg(String boxName, Long boxId){
        pushAll("抢购活动", StringUtils.format("“{}”即将开始发售，去查看~", boxName), PushJumpEnum.BOX_DETAIL, String.valueOf(boxId));
    }

    /**
     * 给用户推送消息
     *
     * @param userId
     */
    private void push(Long userId, String title, String msg, PushJumpEnum jumpType, String data) {
        String registrationId = userPushBindService.getUserPushId(userId);
        if(StringUtils.isEmpty(registrationId)){
            throw new ServiceException("用户未注册推送!");
        }
        Notification.Builder builder = Notification.newBuilder()
                .setAlert(msg);

        builder.addPlatformNotification(AndroidNotification.newBuilder().setTitle(title)
                .addExtra("type", jumpType.getValue())
                .addExtra("data", data)
                .build());
        builder.addPlatformNotification(IosNotification.newBuilder()
                .addExtra("type", jumpType.getValue())
                .addExtra("data", data)
                .build());

        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.registrationId(registrationId))
                .setNotification(builder.build())
                .setOptions(Options.newBuilder().setApnsProduction(apnsProduction).build())
                .build();
        try {
            PushResult pushResult = getClient().sendPush(payload);
            log.info("单一推送完成：{}", JSON.toJSONString(pushResult));
        } catch (Exception e) {
            log.error("单一消息推送失败:userId:{} msg:{}", userId, msg, e);
        }
    }

    /**
     * 给所有用户推送消息
     */
    private void pushAll(String title, String msg, PushJumpEnum jumpType, String data) {
        pushAll(Platform.all(), title, msg, jumpType, data);
    }

    /**
     * 给所有用户推送消息
     */

    private void pushAll(Platform platform, String title, String msg, PushJumpEnum jumpType, String data) {
        if(XQBossConfig.isTestEnable()) {
            log.error("测试环境关闭统一消息推送：{}",  msg);
            return;
        }
        Notification.Builder build = Notification.newBuilder()
                .setAlert(msg);
        build.addPlatformNotification(AndroidNotification.newBuilder().setTitle(title)
                .addExtra("type", jumpType.getValue())
                .addExtra("data", data)
                .build());
        build.addPlatformNotification(IosNotification.newBuilder()
                .addExtra("type", jumpType.getValue())
                .addExtra("data", data)
                .build());

        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(platform)
                .setAudience(Audience.all())
                .setNotification(build.build())
                .setOptions(Options.newBuilder().setApnsProduction(apnsProduction).build())
                .build();
        try {
            PushResult pushResult = getClient().sendPush(payload);
            log.info("统一推送完成：{}", JSON.toJSONString(pushResult));
        } catch (Exception e) {
            log.error("统一消息推送失败：{}",  msg, e);
        }
    }
}
